import os
import sys
import pygame
import random
from cards.plant import Plant

print('你好，世界！')

current_dir = os.path.dirname(os.path.abspath(__file__))
font_file = os.path.join(current_dir, "resources", "wqy-zenhei.ttc")
print(font_file)

# 初始化pygame时设置中文支持
pygame.init()
try:
    # 列出系统中所有的字体
    #print(pygame.font.get_fonts())
    print('Font: simhei')
    # 尝试加载中文字体(需确保系统有该字体或提供字体文件)
    if os.path.exists(font_file):
        font = pygame.font.Font(font_file, 24)
        fontCard = pygame.font.Font(font_file, 16)
        fontBlood = pygame.font.Font(font_file, 9)
    else:
        font = pygame.font.SysFont("simhei", 24)
        fontCard = pygame.font.SysFont('simhei', 16)
        fontBlood = pygame.font.SysFont('simhei', 9)
except:
    # 第二方案（linux用）
    try:
        print('Font: simsum')
        # 尝试加载中文字体(需确保系统有该字体或提供字体文件)
        font = pygame.font.SysFont("simsum", 24)
        fontCard = pygame.font.SysFont('simsum', 16)
        fontBlood = pygame.font.SysFont('simsum', 9)
    except:
        print('Font: Arial')
        # 回退方案
        font = pygame.font.SysFont('Arial', 24)
        fontCard = pygame.font.SysFont('Arial', 16)
        fontBlood = pygame.font.SysFont('Arial', 9)


# 屏幕设置
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("植物大战僵尸简易版")

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
BROWN = (139, 69, 19)
YELLOW = (255, 255, 0)
DARK_YELLOW = (210, 210, 0)
DARK_GREEN = (0, 100, 0)
DARK_BLUE = (0, 0, 100)

# 游戏参数
clock = pygame.time.Clock()
FPS = 60 # 帧数
sun_count = 1000 # 阳光数量
game_over = False # 游戏是否结束
score = 0 # 分数

# 草坪网格
TOP_HEIGHT = 100 # 草坪顶部区域的高度
GRID_SIZE = 80 # 格子大小
GRID_WIDTH = 9 # 格子宽度
GRID_HEIGHT = 5 # 格子高度
lawn = [[None for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)] # 草坪网格，每个格子对应一个植物对象

# 向日葵类
class Sunflower(Plant):
    def __init__(self, row, col, card_attr):
        super().__init__(screen, fontBlood, 0, TOP_HEIGHT, GRID_SIZE, GRID_SIZE, row, col, card_attr, DARK_YELLOW, None)
        self.sun_production_time = 5 * FPS  # 5秒
        self.left_production_time = self.sun_production_time
    
    def update(self):
        super().update()
        self.left_production_time -= 1
        if self.left_production_time <= 0:
            self.left_production_time = self.sun_production_time
            return True
        return False
    
# 豌豆射手类
class Peashooter(Plant):
    def __init__(self, row, col, card_attr):
        super().__init__(screen, fontBlood, 0, TOP_HEIGHT, GRID_SIZE, GRID_SIZE, row, col, card_attr, GREEN, DARK_GREEN)
        self.attack_cooldown = 1 * FPS  # 1秒
    
    def attack(self, zombies):
        if not self.can_attack():
            return None
        
        for zombie in zombies:
            if zombie.row == self.row and zombie.col > self.col:
                self.attack_cooldown = 1 * FPS
                return Projectile(self.row, self.col)
        return None
    
# 坚果墙类
class WallNut(Plant):
    def __init__(self, row, col, card_attr):
        super().__init__(screen, fontBlood, 0, TOP_HEIGHT, GRID_SIZE, GRID_SIZE, row, col, card_attr, BROWN, None, 100)

# 俊熙射手类
class JunXiShooter(Plant):
    def __init__(self, row, col, card_attr):
        super().__init__(screen, fontBlood, 0, TOP_HEIGHT, GRID_SIZE, GRID_SIZE, row, col, card_attr, WHITE, DARK_GREEN)
        self.attack_cooldown = 0.5 * FPS  # 0.5秒

    def attack(self, zombies):
        if not self.can_attack():
            return None
        
        for zombie in zombies:
            if zombie.row == self.row and zombie.col > self.col:
                self.attack_cooldown = 0.5 * FPS
                return Projectile(self.row, self.col)
        return None

# 俊熙坚果墙类
class JunXiNut(Plant):
    def __init__(self, row, col, card_attr):
        super().__init__(screen, fontBlood, 0, TOP_HEIGHT, GRID_SIZE, GRID_SIZE, row, col, card_attr, BLACK, None, 5000)
    
# 投射物类
class Projectile:
    def __init__(self, row, col):
        self.row = row
        self.col = col
        self.x = col * GRID_SIZE + GRID_SIZE // 2 + 30
        self.y = row * GRID_SIZE + GRID_SIZE // 2 + TOP_HEIGHT
        self.speed = 5
        self.damage = 20
    
    def update(self):
        self.x += self.speed
        self.col = int(self.x // GRID_SIZE)
    
    def draw(self, surface):
        pygame.draw.circle(surface, GREEN, (int(self.x), self.y), 10)
    
    def is_out_of_bounds(self):
        return self.x > SCREEN_WIDTH
    
    def collides_with(self, zombie):
        zombie_x = zombie.col * GRID_SIZE + GRID_SIZE // 2
        zombie_y = zombie.row * GRID_SIZE + GRID_SIZE // 2 + TOP_HEIGHT
        distance = ((self.x - zombie_x) ** 2 + (self.y - zombie_y) ** 2) ** 0.5
        return distance < 30

# 爆炸类
class Explosion:
    def __init__(self, row):
        self.row = row
        self.timer = 0.5 * FPS  # 持续半秒
        self.damage = 1000  # 巨大伤害
    
    def update(self, zombies):
        self.timer -= 1
        if self.timer <= 0:
            return True  # 爆炸结束
        
        # 对整行僵尸造成伤害
        for zombie in zombies[:]:
            if zombie.row == self.row:
                zombie.health -= self.damage
        return False
    
    def draw(self, surface):
        # 绘制红色爆炸效果
        y = self.row * GRID_SIZE + GRID_SIZE // 2 + TOP_HEIGHT
        pygame.draw.rect(surface, (255, 100, 0), (0, y - 40, SCREEN_WIDTH, 80))

# 僵尸类
class Zombie:
    def __init__(self, row):
        self.row = row
        self.col = GRID_WIDTH
        self.x = self.col * GRID_SIZE
        self.y = self.row * GRID_SIZE
        self.health = 700
        self.max_health = self.health
        self.speed = 0.5
        self.attack_cooldown = 0
        self.damage = 1
    
    def update(self, plants):
        # 检查前方是否有植物
        plant_in_front = None
        for plant in plants:
            if plant.row == self.row and plant.left <= self.x <= plant.right + GRID_WIDTH // 4:
                plant_in_front = plant
                break
        
        if plant_in_front:
            if self.attack_cooldown <= 0:
                plant_in_front.health -= self.damage
                self.attack_cooldown = 0.25 * FPS
            else:
                self.attack_cooldown -= 1
        else:
            if self.attack_cooldown > 0:
                self.attack_cooldown -= 1
            else:
                self.x -= self.speed
                self.col = int(self.x // GRID_SIZE)
    
    def draw(self, surface):
        x = int(self.x) + GRID_SIZE // 2
        y = self.y + GRID_SIZE // 2 + TOP_HEIGHT
        pygame.draw.rect(surface, (100, 100, 100), (x - 20, y - 30, 40, 60))
        # 绘制血条
        health_width = 40 * (self.health / self.max_health)
        pygame.draw.rect(surface, (255, 0, 0), (x - 20, y - 40, 40, 5))
        pygame.draw.rect(surface, (0, 255, 0), (x - 20, y - 40, health_width, 5))
        # 血条显示文字
        blood_text = fontBlood.render(f"{self.health} / {self.max_health}", True, BLACK)
        text_rect = blood_text.get_rect()
        text_rect.centerx = x
        text_rect.centery = y - 38
        screen.blit(blood_text, text_rect)
    
    def is_dead(self):
        return self.health <= 0
    
    def reached_house(self):
        return self.x <= -19

# 阳光类
class Sun:
    def __init__(self, x, y, is_falling=True):
        self.x = x
        self.y = y
        self.is_falling = is_falling
        self.speed = 2
        self.lifetime = 5 * FPS  # 5秒
        self.radius = 25
    
    def update(self):
        if self.is_falling and self.y < SCREEN_HEIGHT - 100:
            self.y += self.speed
        else:
            self.is_falling = False
            self.lifetime -= 1
    
    def draw(self, surface):
        pygame.draw.circle(surface, YELLOW, (int(self.x), int(self.y)), self.radius)
    
    def is_expired(self):
        return self.lifetime <= 0 and not self.is_falling
    
    def is_clicked(self, pos):
        distance = ((pos[0] - self.x) ** 2 + (pos[1] - self.y) ** 2) ** 0.5
        return distance <= self.radius

# 游戏主循环
plants = []
explosions = []
zombies = []
projectiles = []
suns = []
zombie_spawn_timer = -5 * FPS # 一开始给出5秒的冷却时间，避免玩家刚开始游戏就生成僵尸
sun_spawn_timer = 0
selected_plant = None

# 植物卡片
plant_cards = [
    {"name": "向日葵", "cost": 50, "select_color": YELLOW, "clazz": Sunflower},
    {"name": "豌豆射手", "cost": 100, "select_color": GREEN, "clazz": Peashooter},
    {"name": "坚果墙", "cost": 50, "select_color": BROWN, "clazz": WallNut},
    {"name": "俊熙射手", "cost": 5, "select_color": BLACK, "clazz": JunXiShooter},
    {"name": "高坚果", "cost": 10, "select_color": BLACK, "clazz": JunXiNut},
    {"name": "火爆辣椒", "cost": 20, "select_color": BLACK},
    {"name": "铲子", "select_color": RED}
]

while not game_over:
    # 事件处理
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        
        if event.type == pygame.MOUSEBUTTONDOWN:
            mouse_pos = pygame.mouse.get_pos()
            
            # 检查是否点击了阳光
            for sun in suns[:]:
                if sun.is_clicked(mouse_pos):
                    suns.remove(sun)
                    sun_count += 25
                    break
            else:
                # 检查是否点击了植物卡片
                for card in plant_cards:
                    if card["rect"].collidepoint(mouse_pos):
                        if card["name"] == "铲子":  # 铲子不需要花费阳光
                            selected_plant = card
                            break
                        elif sun_count >= card["cost"]:
                            selected_plant = card
                            break
                else:
                    # 检查是否在草坪上种植植物
                    if selected_plant:
                        col = mouse_pos[0] // GRID_SIZE
                        row = (mouse_pos[1] - TOP_HEIGHT) // GRID_SIZE
                        
                        if 0 <= row < GRID_HEIGHT and 0 <= col < GRID_WIDTH:
                            if selected_plant["name"] == "铲子":
                                for plant in plants[:]:
                                    if plant.row == row and plant.col == col:
                                        print("remove")
                                        plants.remove(plant)
                                        lawn[row][col] = None
                                        if "cost" in plant.card_attr:
                                            sun_count += (plant.card_attr["cost"] // 2)
                                        break
                            elif lawn[row][col] is None and sun_count >= selected_plant["cost"]:
                                if "clazz" in selected_plant and selected_plant["clazz"] is not None:
                                    lawn[row][col] = selected_plant["clazz"](row, col, selected_plant)
                                    plants.append(lawn[row][col])
                                elif selected_plant["name"] == "火爆辣椒":
                                    explosions.append(Explosion(row))  # 整行爆炸
                                sun_count -= selected_plant["cost"]
                            selected_plant = None

                                
    # 游戏更新
    # 生成阳光
    sun_spawn_timer += 1
    if sun_spawn_timer >= 300:  # 每5秒
        sun_spawn_timer = 0
        suns.append(Sun(random.randint(100, SCREEN_WIDTH - 100), 0))
    
    # 生成僵尸
    zombie_spawn_timer += 1
    if zombie_spawn_timer >= 150:  # 每2.5秒
        zombie_spawn_timer = 0
        zombies.append(Zombie(random.randint(0, GRID_HEIGHT - 1)))
    
    # 更新植物
    for plant in plants[:]:
        plant.update()
        
        if isinstance(plant, Sunflower) and plant.update():  # 向日葵产生阳光
            xx = plant.col * GRID_SIZE + GRID_SIZE // 2
            yy = plant.row * GRID_SIZE + GRID_SIZE // 2 + TOP_HEIGHT
            suns.append(Sun(xx, yy, False))
        
        if hasattr(plant, 'attack'):
            projectile = plant.attack(zombies)
            if projectile:
                projectiles.append(projectile)
        
        if plant.health <= 0:
            plants.remove(plant)
            lawn[plant.row][plant.col] = None
    
    # 更新投射物
    for projectile in projectiles[:]:
        projectile.update()
        
        # 检查碰撞
        for zombie in zombies[:]:
            if projectile.collides_with(zombie):
                zombie.health -= projectile.damage
                if projectile in projectiles:
                    projectiles.remove(projectile)
                break
        
        if projectile.is_out_of_bounds() and projectile in projectiles:
            projectiles.remove(projectile)
    
    # 更新僵尸
    for zombie in zombies[:]:
        zombie.update(plants)
        
        if zombie.is_dead():
            zombies.remove(zombie)
            score += 10
        elif zombie.reached_house():
            game_over = True
    
    # 更新阳光
    for sun in suns[:]:
        sun.update()
        if sun.is_expired():
            suns.remove(sun)
    
    # 更新爆炸效果
    for explosion in explosions[:]:
        if explosion.update(zombies):
            explosions.remove(explosion)
            print('删除爆炸效果')

    # 绘制
    screen.fill((200, 200, 200))
    
    # 绘制草坪网格
    for row in range(GRID_HEIGHT):
        for col in range(GRID_WIDTH):
            rect = pygame.Rect(col * GRID_SIZE, row * GRID_SIZE + TOP_HEIGHT, GRID_SIZE, GRID_SIZE)
            pygame.draw.rect(screen, (100, 200, 100) if (row + col) % 2 == 0 else (120, 220, 120), rect)
            pygame.draw.rect(screen, BLACK, rect, 1)
    
    # 绘制植物卡片区域
    pygame.draw.rect(screen, (200, 150, 100), (0, 0, SCREEN_WIDTH, TOP_HEIGHT))
    left = 10
    for card in plant_cards:
        card["rect"] = pygame.Rect(left, 10, 70, 90)
        pygame.draw.rect(screen, (150, 100, 50), card["rect"])
        text = fontCard.render(card["name"], True, BLACK)
        screen.blit(text, (card["rect"].x + 5, card["rect"].y + 5))
        if 'cost' in card:
            cost_text = fontCard.render(f"${card['cost']}", True, YELLOW)
            screen.blit(cost_text, (card["rect"].x + 5, card["rect"].y + 40))
        left += 80
    
    # 绘制阳光计数
    sun_text = font.render(f"阳光: {sun_count}", True, BLACK)
    screen.blit(sun_text, (SCREEN_WIDTH - 150, 10))
    
    # 绘制分数
    score_text = font.render(f"分数: {score}", True, BLACK)
    screen.blit(score_text, (SCREEN_WIDTH - 150, 50))
    
    # 绘制植物
    for plant in plants:
        plant.draw(screen)
    
    # 绘制僵尸
    for zombie in zombies:
        zombie.draw(screen)
    
    # 绘制投射物
    for projectile in projectiles:
        projectile.draw(screen)
    
    # 绘制阳光
    for sun in suns:
        sun.draw(screen)
    
    # 绘制选中的植物
    if selected_plant:
        mouse_pos = pygame.mouse.get_pos()
        col = mouse_pos[0] // GRID_SIZE
        row = (mouse_pos[1] - TOP_HEIGHT) // GRID_SIZE
        
        if 0 <= row < GRID_HEIGHT and 0 <= col < GRID_WIDTH:
            x = col * GRID_SIZE + GRID_SIZE // 2
            y = row * GRID_SIZE + GRID_SIZE // 2 + TOP_HEIGHT
            
            if "select_color" in selected_plant and selected_plant["select_color"] is not None:
                pygame.draw.circle(screen, selected_plant["select_color"], (x, y), 30, 2)
    
    # 绘制爆炸效果
    for explosion in explosions:
        explosion.draw(screen)
                
    # 游戏结束检查
    if game_over:
        game_over_text = font.render("游戏结束! 按R键重新开始", True, (255, 0, 0))
        screen.blit(game_over_text, (SCREEN_WIDTH // 2 - 150, SCREEN_HEIGHT // 2))
        pygame.display.flip()
        
        waiting = True
        while waiting:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_r:
                        # 重置游戏
                        plants = []
                        zombies = []
                        projectiles = []
                        suns = []
                        lawn = [[None for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
                        sun_count = 50
                        score = 0
                        zombie_spawn_timer = 0
                        sun_spawn_timer = 0
                        selected_plant = None
                        game_over = False
                        waiting = False
    
    pygame.display.flip()
    clock.tick(FPS)
